<?php
    class Core_Nosql  extends Core_Base
    {
        private $client;
        public $lastResult;
        function __construct()
        {
            if (!empty($GLOBALS['__LOCAL']['nosql']) && strtolower($GLOBALS['__LOCAL']['nosql']['id']) == 'elasticsearch' && is_numeric(strpos(PHP_VERSION, '5.6.'))) {
                try {
                    set_include_path(SYSTEM_LIBRARY_DIR);
                    require SYSTEM_LIBRARY_DIR . DS . 'vendor' . DS . 'autoload.php';
                    $this->client = Elasticsearch\ClientBuilder::create()->setHosts(array($GLOBALS['__LOCAL']['nosql']['hosts']))->build();
                    sfconsole('nosql success');
                } catch (Exception $e) {
                    $this->client = false;
                    sfconsole('nosql failure');
                }
            } else {
                sfconsole('nosql not config');
            }
        }

        public function isEnable()
        {
            return !empty($this->client);
        }

        public function batch($index, $type, $datas = array(), $param = array())
        {
            if (!$this->isEnable()) {
                return false;
            }
            $bulk = array('index' => $index, 'type' => $type, 'body' => array());
            for ($i = 0, $count = count($datas); $i < $count; $i++) {
                $bulk['body'][] = array('index' => array('_index' => $index, '_type' => $type));
                $bulk['body'][] = $datas[$i];
            }
            return $this->client->bulk($bulk);
        }

        public function add($index, $type, $data = array(), $param = array())
        {
            if (!$this->isEnable()) {
                return false;
            }
            list($usec, $sec)   =   explode(' ', microtime());
            $data['_i'] = $sec + $usec;
            $data['_i'] = explode('.', $data['_i']);
            $data['_i'][1] = sprintf('%04s', $data['_i'][1]);
            $data['_i'] = implode('', $data['_i']);
            $args = array();
            $args['index'] = $index;
            $args['type'] = $type;
            foreach ($data as $key => $value) {
                if (empty($value) && $value !== 0) {
                    unset($data[$key]);
                }
            }
            $args['body'] = $data;
            return $this->client->index($args);
        }

        public function get($index, $type, $param = array())
        {
            if (!$this->isEnable()) {
                return false;
            }
            $args = array();
            $args['index'] = $index;
            $args['type'] = $type;
            if ($param['limit']) {
                $args['size'] = $param['limit'];
            }

            if (!empty($param['order'])) {
                if (empty($args['body'])) {
                    $args['body'] = array('sort' => array());
                }
                if (!isset($args['body']['sort'])) {
                    $args['body']['sort'] = array();
                }
                for ($i=0, $index = count($param['order']); $i < $index; $i++) {
                    list($field, $by) = explode(' ', $param['order']);
                    $args['body']['sort'][$field] = array('order' => $by);
                }
            }
            if (empty($args['body']['sort']['_i'])) {
                if (empty($args['body'])) {
                    $args['body'] = array('sort' => array());
                }
                if (!isset($args['body']['sort'])) {
                    $args['body']['sort'] = array();
                }
                $args['body']['sort']['_i'] = array('order' => 'desc');
            }
            if (!empty($param['where'])) {
                foreach ($param['where'] as $key => $value) {
                    switch (strtolower($key)) {
                        case 'and':
                            if (empty($args['body'])) {
                                $args['body'] = array();
                            }
                            if (empty($args['body']['query'])) {
                                $args['body']['query'] = array();
                            }
                            if (empty($args['body']['query']['bool'])) {
                                $args['body']['query']['bool'] = array();
                            }
                            if (empty($args['body']['query']['bool']['must'])) {
                                $args['body']['query']['bool']['must'] = array();
                            }
                            foreach ($value as $k => $v) {
                                $args['body']['query']['bool']['must'][] = array('match' => array($k => $v));
                            }
                            break;
                    }
                }
            }
            if (!empty($param['args'])) {
                foreach ($param['args'] as $key => $value) {
                    if (is_array($value)) {
                        foreach ($value as $k => $v) {
                            if (is_array($v)) {
                                foreach ($v as $k1 => $v1) {
                                    if (is_array($v1)) {
                                        foreach ($v1 as $k2 => $v2) {
                                            if (is_array($v2)) {
                                                foreach ($v2 as $k3 => $v3) {
                                                    $args[$key][$k][$k1][$k2][$k3] = $v3;
                                                }
                                            } else {
                                                $args[$key][$k][$k1][$k2] = $v2;
                                            }
                                        }
                                    } else {
                                        $args[$key][$k][$k1] = $v1;
                                    }
                                }
                            } else {
                                $args[$key][$k] = $v;
                            }
                        }
                    } else {
                        $args[$key] = $value;
                    }
                }
            }
            sfconsole(json_encode($args['body']));
            try {
                $datas = $this->client->search($args);
            } catch (Exception $e) {
            }
            $this->lastResult = $datas;
            if (!empty($datas)) {
                $fDatas = array();
                for ($i = 0, $index = count($datas['hits']['hits']); $i < $index; $i++) {
                    $fDatas[$i] = $datas['hits']['hits'][$i]['_source'];
                    $fDatas[$i]['__'] = $datas['hits']['hits'][$i];
                }
                $datas = $fDatas;
            }
            return $datas;
        }

        public function del($index, $type, $id)
        {
            if (!$this->isEnable()) {
                return false;
            }
            try {
                $args = array();
                $args['index'] = $index;
                $args['type'] = $type;
                $args['id'] = $id;
                return $this->client->delete($args);
            } catch (Exception $e) {

            }
            return false;
        }

        public function getLastTotal()
        {
            if (!$this->isEnable()) {
                return false;
            }
            return $this->lastResult['hits']['total'];
        }
    }